﻿using System;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ServiceModel.DomainServices.Client;
using System.Collections.Generic;
using Microsoft.Practices.Composite.Presentation.Commands;
using Scoreboard.Model;
using Scoreboard.Interfaces;
using Microsoft.Practices.Composite.Events;
using Scoreboard.Scripting;
using Scoreboard.Data;
using Scoreboard.Basement;
using Scoreboard.Basement.Events;
using Scoreboard.Basement.ViewModels;

namespace Scoreboard.TournamentManagement
{
	public class ViewModel : PageViewModel
	{
		private readonly ITournamentRepository _repository;
		private IEnumerable<Tournament> _tournaments;
		private Tournament _selectedTournament;
		private string _scriptText = string.Empty;

		public ViewModel(ITournamentRepository repository)
		{
			_repository = repository;

			SubmitChangesCommand = new DelegateCommand<object>(SubmitChangesCommandHandler);
			DiscardChangesCommand = new DelegateCommand<object>(DiscardChangesCommandHandler);
			AddTournamentCommand = new DelegateCommand<object>(AddTournamentCommandHandler);
			DeleteTournamentCommand = new DelegateCommand<object>(DeleteTournamentCommandHandler);
			ExecuteScriptCommand = new DelegateCommand<object>(ExecuteScriptCommandHandler);
			AddSomePlayersCommand = new DelegateCommand<object>(AddSomePlayersCommandHandler);

			AddUpdater(EntityTypes.Tournaments, LoadTournaments);

			FillCommands();
		}

		private void FillCommands()
		{
			Commands.Add(new UserCommand("Сохранить изменения", SubmitChangesCommand));
			Commands.Add(new UserCommand("Отменить изменения", DiscardChangesCommand));
			Commands.Add(new UserCommand("Создать турнир", AddTournamentCommand));
			Commands.Add(new UserCommand("Удалить турнир", DeleteTournamentCommand));
			Commands.Add(new UserCommand("Выполнить скрипт", ExecuteScriptCommand));
			Commands.Add(new UserCommand("Добавить игроков", AddSomePlayersCommand));
			Commands.Add(new UserCommand("Очистить", new DelegateCommand<object>(o =>
			{
				var stages = SelectedTournament.Stages;
				foreach (var stage in stages)
				{
					SelectedTournament.Stages.Remove(stage);
				}
			})));

														
		}

		protected override string Name
		{
			get
			{
				return "Tournaments Management";
			}
		}

		public IEnumerable<Tournament> Tournaments
		{
			get
			{
				if (_tournaments == null)
				{
					LoadTournaments();
				}
				return _tournaments;
			}
			set
			{
				_tournaments = value;
				FirePropertyChanged("Tournaments");
			}
		}

		public Tournament SelectedTournament
		{
			get
			{
				return _selectedTournament;
			}
			set
			{
				_selectedTournament = value;
				FirePropertyChanged("SelectedTournament");
			}
		}

		public string ScriptText
		{
			get
			{
				return _scriptText;
			}
			set
			{
				_scriptText = value;
				FirePropertyChanged("ScriptText");
			}
		}

		private ICommand SubmitChangesCommand { get; set; }
		private ICommand AddTournamentCommand { get; set; }
		private ICommand DeleteTournamentCommand { get; set; }
		private ICommand DiscardChangesCommand { get; set; }
		private ICommand ExecuteScriptCommand { get; set; }
		private ICommand AddSomePlayersCommand { get; set; }

		private void LoadTournaments()
		{
			Tournaments = _repository.GetTournamentsLive();
		}

		private void SubmitChangesCompleted(SubmitOperation operation)
		{
			if (!operation.HasError)
			{
				var eventAggregator = ServiceLocator.Get<IEventAggregator>();
				var dataChangedEvent = eventAggregator.GetEvent<DataChangedEvent>();
				dataChangedEvent.Publish(EntityTypes.Tournaments);
			}
		}

		#region // Command handlers

		private void SubmitChangesCommandHandler(object parameter)
		{
			_repository.SubmitChanges(SubmitChangesCompleted);
		}

		private void DiscardChangesCommandHandler(object parameter)
		{
			_repository.DiscardChanges();
		}

		private void AddTournamentCommandHandler(object parameter)
		{
			var dialogService = ServiceLocator.Get<IDialogService>();

			var viewModel = new AddTournamentDialogViewModel(_repository);
			var addTournamentDialog = new AddTournamentDialog(viewModel);
			dialogService.ShowDialog(addTournamentDialog);
		}

		private void DeleteTournamentCommandHandler(object parameter)
		{
			if (SelectedTournament != null)
			{
				_repository.DeleteTournament(SelectedTournament);
			}
		}

		private void ExecuteScriptCommandHandler(object parameter)
		{
			var executor = new ScriptExecutor();
			executor.Run(SelectedTournament, ScriptText);
			FirePropertyChanged("SelectedTournament");
		}

		private void AddSomePlayersCommandHandler(object parameter)
		{
			if (SelectedTournament == null)
			{
				return;
			}
			var me = new Participant { Player = _repository.CurrentUser };
			SelectedTournament.Participants.Add(me);

			var usersRepository = ServiceLocator.Get<IUserRepository>();
			var users = usersRepository.GetPreloadedUsers();
			foreach (var user in users.OrderByDescending(u => u.RatingValue).Take(7))
			{
				var participant = new Participant { Player = user };
				SelectedTournament.Participants.Add(participant);
			}

			_repository.SubmitChanges();
		}

		#endregion
	}
}
